/* 
 * File:   FileWindow.cpp
 * Author: mauro
 * 
 * Created on 13 de octubre de 2014, 16:51
 */

#include <functional>
#include "FileWindow.h"
#include "DefaultValues.h"

using namespace std;

FileWindow::FileWindow(const char* sourcePath) {
    this -> fileName = sourcePath;
    this->loadWindow();
}

FileWindow::~FileWindow() {
    delete this->endObject;   
    delete this->polygonFive;
    delete this->polygonSix;
    delete this->polygonThree;
    delete this->rectangle;
    delete this->trapezium;
    delete this->circle;
    delete this->parrallellogram;
    
}
FileWindow::FileWindow(bool loadall) {
    this->loadDefaultWindow(true, true, true, true, true, true, true, true, true);
}

void FileWindow::loadWindow() { // Read JSON from a file
    SBSLog* myLogFile;
    myLogFile->getInstance(MY_LOG_MODE);
    myLogFile->writeInLog(0, "[0] Se inicia el parseo del archivo de escenario.\n");
    try {
        JSON::Value fileMap = parse_file(this->fileName);
//        if (fileMap["nombre"].type() == JSON::STRING) {
//            this -> name = ((fileMap["nombre"]).as_string());
//            myLogFile->writeInLog(0, "[0] Se parseo exitosamente el nombre de la ventana.\n");
//        } else {
//            myLogFile->writeInLog(1, "[1] El nombre de ventana no esta en el archivo o no tiene un valor valido.  Se tomara el valor por default[GAME_NAME]\n");
//            this->loadDefaultWindow(true, false, false, false, false, false, false, false, false, 0, false);
//        }
        
//        if (fileMap["gravedad"].type() == JSON::INT) {
//            this -> gravity = (float) (fileMap["gravedad"]).as_int();
//            myLogFile->writeInLog(1, "[1] Se recibio un INTEGER y se esperaba un FLOAT para la gravedad del mundo.  Se seteo el valor ingresado exitosamente.\n");
//        } else {
//            if (fileMap["gravedad"].type() == JSON::FLOAT) {
//                this -> gravity = (fileMap["gravedad"]).as_float();
//                myLogFile->writeInLog(0, "[0] Se parseo exitosamente la gravedad del mundo SBS.\n");
//            } else {
//                myLogFile->writeInLog(1, "[1] La gravedad no esta en el archivo o no tiene un valor valido.  Se tomara el valor por default [WORLD_GRAVITY]\n");
//                this->loadDefaultWindow(false, true, false, false, false, false, false, false, false, 0, false);
//            }
//        }
        
        if (fileMap["escenario"].type() == JSON::OBJECT) {
            JSON::Object nivel = ((fileMap["escenario"]).operator JSON::Object());
            myLogFile->writeInLog(0, "[0] El TAG escenario correctamente definido, se procede a parsear los atributos del escenario.\n");
            if (nivel["fondo"].type() == JSON::STRING) {
                ifstream checkFile((nivel["fondo"]).as_string(), ios::out | ios::binary);
                if (checkFile.good()) {
                    this -> backGround = ((nivel["fondo"]).as_string());
                    myLogFile->writeInLog(0, "[0] Se parseo la ruta de la imagen de fondo exitosamente\n");
                } else {
                    myLogFile->writeInLog(1, "[1] No existe el archivo de imagen de fondo.  Se tomara la imagen defaul [SCREEN_BACKGROUND]. \n");
                    this->loadDefaultWindow(false, false, true, false, false, false, false, false, false);
                }

            } else {
                myLogFile->writeInLog(1, "El TAG fondo no esta en el archivo o no tiene un tipo de dato valido. Se tomara el valor por default [SCREEN_BACKGROUND]\n");
                this->loadDefaultWindow(false, false, true, false, false, false, false, false, false);
            }

            if (nivel["altoPx"].type() == JSON::INT) {
                this -> pixelHeight = ((nivel["altoPx"]).as_int());
                myLogFile->writeInLog(0, "[0] Se parseo el alto en pixeles de la ventana exitosamente\n");
            } else {
                myLogFile->writeInLog(1, "[1] El alto en pixeles de la ventana no esta en el archivo o no tiene un valor valido.  Se tomara el valor por default [SCREEN_HEIGHT]\n");
                this->loadDefaultWindow(false, false, false, true, false, false, false, false, false);
            }
            if (nivel["anchoPx"].type() == JSON::INT) {
                this -> pixelWidth = ((nivel["anchoPx"]).as_int());
                myLogFile->writeInLog(0, "[0] Se parseo el ancho en pixeles de la ventana exitosamente\n");
            } else {
                myLogFile->writeInLog(1, "[1] El ancho en pixeles de la ventana no esta en el archivo o no tiene un valor valido.  Se tomara el valor por default [SCREEN_WIDTH]\n");
                this->loadDefaultWindow(false, false, false, false, true, false, false, false, false);
            }
            if (nivel["altoUn"].type() == JSON::INT) {
                this -> logicalUnitH = ((nivel["altoUn"]).as_int());
                myLogFile->writeInLog(0, "[0] Se parseo el alto en unidades logicas de la ventana exitosamente\n");
            } else {
                myLogFile->writeInLog(1, "[1] El ancho en unidades lotruegicas de la ventana no esta en el archivo o no tiene un valor valido.  Se tomara el valor por default DEFAULT_LOGICAL_W\n");
                this->loadDefaultWindow(false, false, false, false, false, true, false, false, false);
            }
            if (nivel["anchoUn"].type() == JSON::INT) {
                this -> logicalUnitW = ((nivel["anchoUn"]).as_int());
                myLogFile->writeInLog(0, "[0] Se parseo el ancho en unidades logicas de la ventana exitosamente\n");
            } else {
                myLogFile->writeInLog(1, "[1] El ancho en unidades logicas de la ventana no esta en el archivo o no tiene un valor valido.  Se tomara el valor por default DEFAULT_LOGICAL_H\n");
                this->loadDefaultWindow(false, false, false, false, false, false, true, false, false);
            }
            
            if (nivel["conexiones"].type() == JSON::INT) {
                this ->maxPlayers = ((nivel["conexiones"]).as_int());
                myLogFile->writeInLog(0, "[0] Se parseo el maximo permitido de jugadores simultaneos exitosamente\n");
            } else {
                myLogFile->writeInLog(1, "[1] El maximo permitido de jugadores simultaneos no esta en el archivo o no tiene un valor valido.  Se tomara el valor por default DEFAULT_LOGICAL_H\n");
                this->loadDefaultWindow(false, false, false, false, false, false, true, false, false);
            }
            
//            if (nivel["personaje"].type() == JSON::OBJECT) {
//                JSON::Object character((nivel["personaje"]).operator JSON::Object());
//                players = new FileCharacter((character["x"]).as_int(), (character["y"]).as_int());
//                myLogFile->writeInLog(0, "[0] Se parsearon los datos del personaje exitosamente\n");
//            } else {
//                myLogFile->writeInLog(1, "[1] La posicion X e Y del personaje no estan en el archivo o no tienen valores valido.  Se tomara el valor por default [CHARACTER_POSITION_X,CHARACTER_POSITION_Y]\n");
//                this->loadDefaultWindow(false, false, false, false, false, false, false, true, true, 0, false);
//            }
            if ((nivel["personajes"]).type() == JSON::ARRAY) {
                JSON::Array personajes((nivel["personajes"]).operator JSON::Array());
                int tamanio = (personajes.size());
                if (tamanio <= 0) {
                    myLogFile->writeInLog(1, "[1] La informacion de los jugadores no se encontraba en el archivo.  Se cargaran las posiciones por default.\n");
                    this->creatDefaultCharacters();
                } else {
//                    this ->maxPlayers = tamanio;
                    this -> players.reserve(tamanio);
                    FileCharacter fc;
                    for (int cont = 0; cont < tamanio; ++cont) {
                        if ((personajes[cont]).type() == JSON::OBJECT) {
                            if (fc.assignCharacter(personajes[cont], fc)){
                                players.push_back(fc);
                            } else {
                                string s;
                                s.append("[1] El jugador de id=  ");
                                s.append(to_string(cont));
                                s.append(" se descarto por un valor invalido o faltante.\n");
                                myLogFile->writeInLog(1, s);
                            }
                        }
                    }
                }
            } else {
                myLogFile->writeInLog(1, "[1] El conjunto de jugadores no se encontraba en el archivo o el nombre del TAG no era correcto.  Se cargaran los jugadores en las posiciones por default \n");
                this->creatDefaultCharacters();
            }

            
            
            
            
            if ((nivel["objetos"]).type() == JSON::ARRAY) {
                JSON::Array objetos((nivel["objetos"]).operator JSON::Array());
                int tamanio = (objetos.size());
                if (tamanio <= 0) {
                    myLogFile->writeInLog(1, "[1] El conjunto de figuras del escenario no se encontraba en el archivo.  Se cargaran las figuras por default.\n");
                    //this->creatDefaultObjects();
                } else {
                    this -> objectsNumber = tamanio;
                    this -> objects.reserve(tamanio);
                    FileObjects fo;
                    for (int cont = 0; cont < tamanio; ++cont) {
                        if ((objetos[cont]).type() == JSON::OBJECT) {
                            if (fo.assignObject(objetos[cont], fo, this->pixelWidth, this->pixelHeight, this->logicalUnitW, this->logicalUnitH)) {
                                objects.push_back(fo);
                            } else {
                                string s;
                                s.append("[1] El objeto en la posicion ");
                                s.append(to_string(cont));
                                s.append(" se descarto por un valor invalido o faltante.\n");
                                myLogFile->writeInLog(1, s);
                            }
                        }
                    }
                }
            } else {
                myLogFile->writeInLog(1, "[1] El conjunto de figuras del escenario no se encontraba en el archivo o el nombre del TAG no era correcto.  Se cargaran las figuras por default (3: rectangulo, paralelogramo, cuadrado)\n");
                //this->creatDefaultObjects();
            }
        } else {
            this->loadDefaultWindow(false, false, true, true, true, true, true, true, true);
            myLogFile->writeInLog(1, "[1] Los valores del escenario no se encontraban en el archivo o el nombre del TAG no era correcto.  Se cargara el nivel por default.\n");
        }
    } catch (runtime_error myRE) {
        myLogFile->writeInLog(2, "[2] Se detectaron errores de sintaxis al parsear el archivo JSON.  El error fue el siguiente: ");
        myLogFile->writeInLog(2, myRE.what());
        myLogFile->writeInLog(2, "\n");
        myLogFile->writeInLog(2, "Se cargaran todos los valores por default para el escenario.\n");
        this->loadDefaultWindow(true, true, true, true, true, true, true, true, true);
    } catch (invalid_argument myIA){
        myLogFile->writeInLog(2, "[2] Se detecto un error de argumento invalido al parsear el archivo JSON.  El error fue el siguiente: ");
        myLogFile->writeInLog(2, myIA.what());
        myLogFile->writeInLog(2, "\n");
        myLogFile->writeInLog(2, "Se cargaran todos los valores por default para el escenario.\n");
        this->loadDefaultWindow(true, true, true, true, true, true, true, true, true);
    }
    
    this->filterOverlap();
}

void FileWindow::loadDefaultWindow(bool dn, bool dg, bool db, bool dph, bool dpw, bool dluh, bool dluw, bool dplay, bool dobj) {
    if (dn)this->name = GAME_NAME;
    if (dg) this->gravity = WORLD_GRAVITY;
    if (db) this -> backGround = SCREEN_BACKGROUND;
    if (dph) this -> pixelHeight = SCREEN_HEIGHT;
    if (dpw) this -> pixelWidth = SCREEN_WIDTH;
    if (dluh) this -> logicalUnitH = DEFAULT_LOGICAL_H;
    if (dluw) this -> logicalUnitW = DEFAULT_LOGICAL_W;
    if (dplay) this->creatDefaultCharacters();
    //if (dobj) this->creatDefaultObjects();
}

bool FileWindow::reloadWindow() {
    this->loadWindow(); //Recarga de ventana
    return true;
}

void FileWindow::creatDefaultObjects() {
    FileObjects fo;
    this->objectsNumber = 3; //cargo 3 objetos por default
    this->objects.reserve(this->getObjectsNumber());
    //Cargo el primer rectangulo por default
    fo.setType("RECTANGLE");
    fo.setXCoordinate(250);
    fo.setYCoordinate(500);
    fo.setWidth(100);
    fo.setHeight(50);
    fo.setColor("#FF66B2");
    fo.setRotation(0);
    fo.setMass(2);
    fo.setStatic(true);

    this->objects.push_back(fo);
    
    //Cargo el primer rectangulo por default
    fo.setType("RECTANGLE");
    fo.setXCoordinate(450);
    fo.setYCoordinate(400);
    fo.setWidth(200);
    fo.setHeight(50);
    fo.setColor("#FF66B2");
    fo.setRotation(0);
    fo.setMass(2);
    fo.setStatic(true);

    this->objects.push_back(fo);

    //Cargo el primer rectangulo por default
    fo.setType("RECTANGLE");
    fo.setXCoordinate(650);
    fo.setYCoordinate(300);
    fo.setWidth(50);
    fo.setHeight(50);
    fo.setColor("#FF66B2");
    fo.setRotation(0);
    fo.setMass(2);
    fo.setStatic(true);

    this->objects.push_back(fo);

}

void FileWindow::creatDefaultCharacters(){
    FileCharacter fc;
    
    this->players.reserve(this->getMaxPlayers());
    //Cargo el primer rectangulo por default
    
    fc.setPlayerID(1);
    fc.setXCoordinate(50);
    fc.setYCoordinate(400);
    this->players.push_back(fc);
    
    fc.setPlayerID(2);
    fc.setXCoordinate(100);
    fc.setYCoordinate(400);
    this->players.push_back(fc);
    
    fc.setPlayerID(3);
    fc.setXCoordinate(150);
    fc.setYCoordinate(400);
    this->players.push_back(fc);
    
    fc.setPlayerID(4);
    fc.setXCoordinate(200);
    fc.setYCoordinate(400);
    this->players.push_back(fc);
    
}


bool overlap(FileObjects &unObj, FileObjects &otroObj) {
    //angulo de rotacion.
    float borde = -0.01;
    // printf("ENTRO A OVERLAP\n");
    b2Rot rotA(unObj.getRotation());

    //Coordinate element A
    b2Vec2 vecA(unObj.getXCoordinate(), unObj.getYCoordinate());
    b2Transform tranA(vecA, rotA);
    //Coordinate element B
    b2Vec2 vecB(otroObj.getXCoordinate(), otroObj.getYCoordinate());
    b2Rot rotB(otroObj.getRotation());
    b2Transform tranB(vecB, rotB);

    //    printf("POOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOS   unX: %d unY:%d  otroX:%d otroY:%d \n", unObj.getXCoordinate(), unObj.getYCoordinate(), otroObj.getXCoordinate(), otroObj.getYCoordinate());
    //para guardar los puntos de contacto.
    b2Manifold mani;
    mani.pointCount = 0;
    //mismo tipo de elemento.

    //INICIO TRAPECIO CONTRA TODOS 
    if ((strcmp(unObj.getType().c_str(), "TRAPEZIUM") == 0)) {
        b2PolygonShape polyA;
        float sizeY = unObj.getHeight() / 2;
        float sizeX = unObj.getBase() / 2;
        float alpha = unObj.getAngle1();
        float beta = unObj.getAngle2();
        float adyAlpha = sizeY * cos(alpha) / sin(alpha) * 2;
        float adyBeta = sizeY * cos(beta) / sin(beta) * 2;
        b2Vec2 points[4];
        points[0].Set((-1) * sizeX, sizeY);
        points[1].Set(sizeX, sizeY);
        points[2].Set(sizeX - adyBeta, (-1) * sizeY);
        points[3].Set(adyAlpha - sizeX, (-1) * sizeY);
        polyA.Set(points, 4);
        if ((strcmp(otroObj.getType().c_str(), "TRAPEZIUM") == 0)) {
            //            printf("vs TRAPEZIUM \n");
            b2PolygonShape polyB;
            float sizeYB = otroObj.getHeight() / 2;
            float sizeXB = otroObj.getBase() / 2;
            float alphaB = otroObj.getAngle1();
            float betaB = otroObj.getAngle2();
            float adyAlphaB = sizeYB * cos(alphaB) / sin(alphaB) * 2;
            float adyBetaB = sizeYB * cos(betaB) / sin(betaB) * 2;
            b2Vec2 pointsB[4];
            pointsB[0].Set((-1) * sizeXB, sizeYB);
            pointsB[1].Set(sizeXB, sizeYB);
            pointsB[2].Set(sizeXB - adyBetaB, (-1) * sizeYB);
            pointsB[3].Set(adyAlphaB - sizeXB, (-1) * sizeYB);
            polyB.Set(pointsB, 4);
            b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
        }
        if ((strcmp(otroObj.getType().c_str(), "RECTANGLE") == 0)) {
            //            printf("vs RECTANGLE\n");
            //inicio rectangle
            b2PolygonShape box;
            box.SetAsBox(borde + otroObj.getWidth() / 2, borde + otroObj.getHeight() / 2);
            b2CollidePolygons(&mani, &polyA, tranA, &box, tranB);
        }
        if ((strcmp(otroObj.getType().c_str(), "CIRCLE") == 0)) {
            //            printf("vs CIRCLEEE  escale:%4.3f \n", borde+otroObj.getScale());
            b2CircleShape circle;
            circle.m_radius = borde + otroObj.getScale();

            b2CollidePolygonAndCircle(&mani, &polyA, tranA, &circle, tranB);
        }
        if ((strcmp(otroObj.getType().c_str(), "PARALLELLOGRAM") == 0)) {
            //            printf("vs PARALLELLOGRAMO\n");           
            b2PolygonShape polyB;
            float alphaB = otroObj.getAngle1();
            float sizeYB = otroObj.getHighParall() / 2;
            float sizeXB = otroObj.getBase() / 2;
            float sideB = (sizeYB) / sin(alphaB) * 2;
            float adyB = cos(alphaB) * sideB;
            b2Vec2 pointsB[4]; // paralelogramo = 4 lados
            pointsB[0].Set(adyB - (sizeXB), (-1)*(sizeYB));
            pointsB[1].Set(adyB + (sizeXB), (-1)*(sizeYB));
            pointsB[2].Set((sizeXB), (sizeYB));
            pointsB[3].Set((-1)*(sizeXB), (sizeYB));
            polyB.Set(pointsB, 4);

            b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
        }
        if (strcmp(otroObj.getType().c_str(), "POLYGON") == 0) {
            if (otroObj.getSides() == 3) {
                //                printf("vs TRIANGULO \n");
                int sides = otroObj.getSides();
                b2Vec2 points[sides];
                float scale = otroObj.getScale();
                float x, y;
                int k;
                b2PolygonShape polyB;
                float side = ((2 * scale) * sin(M_PI / sides));
                for (k = 0; k < sides; k++) {
                    x = side * cos(2 * M_PI * k / sides);
                    y = side * sin(2 * M_PI * k / sides);
                    points[k].Set(x, y);
                }
                polyB.Set(points, sides);
                b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
            }
            if (otroObj.getSides() == 5) {
                //                printf("vs POLIGONO 5\n");
                int sides = otroObj.getSides();
                b2Vec2 points[sides];
                float scale = otroObj.getScale();
                float x, y;
                int k;
                b2PolygonShape polyB;
                float side = ((2 * scale) * sin(M_PI / sides));
                for (k = 0; k < sides; k++) {
                    x = side * cos(2 * M_PI * k / sides);
                    y = side * sin(2 * M_PI * k / sides);
                    points[k].Set(x, y);
                }
                polyB.Set(points, sides);
                b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
            }
            if (otroObj.getSides() == 6) {
                //                printf("vs POLYGONO 6\n");
                int sides = otroObj.getSides();
                b2Vec2 points[sides];
                float scale = otroObj.getScale();
                float x, y;
                int k;
                b2PolygonShape polyB;
                float side = ((2 * scale) * sin(M_PI / sides));
                for (k = 0; k < sides; k++) {
                    x = side * cos(2 * M_PI * k / sides);
                    y = side * sin(2 * M_PI * k / sides);
                    points[k].Set(x, y);
                }
                polyB.Set(points, sides);
                b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
            }
        }//end polygon 

    }

    //RECTANGULO CONTRA TODOS
    if (strcmp(unObj.getType().c_str(), "RECTANGLE") == 0) {

        b2PolygonShape boxA;
        boxA.SetAsBox(borde + unObj.getWidth() / 2, borde + unObj.getHeight() / 2);
        //comparo contra un rectangulo
        if (strcmp(otroObj.getType().c_str(), "RECTANGLE") == 0) {
            //            printf("RECTANGLE VS RECTANGLE \n");
            b2PolygonShape boxB;
            boxB.SetAsBox(borde + otroObj.getWidth() / 2, borde + otroObj.getHeight() / 2);
            b2CollidePolygons(&mani, &boxA, tranA, &boxB, tranB);
        }
        if (strcmp(otroObj.getType().c_str(), "CIRCLE") == 0) {
            // printf("RECTANGLE VS CIRCLE \n");
            b2CircleShape circle;
            circle.m_radius = borde + otroObj.getScale();
            b2CollidePolygonAndCircle(&mani, &boxA, tranA, &circle, tranB);
        }
        if (strcmp(otroObj.getType().c_str(), "POLYGON") == 0) {
            if (otroObj.getSides() == 3) {
                int sides = otroObj.getSides();
                b2Vec2 points[sides];
                float scale = otroObj.getScale();
                float x, y;
                int k;
                b2PolygonShape polyB;
                float side = ((2 * scale) * sin(M_PI / sides));
                for (k = 0; k < sides; k++) {
                    x = side * cos(2 * M_PI * k / sides);
                    y = side * sin(2 * M_PI * k / sides);
                    points[k].Set(x, y);
                }
                polyB.Set(points, sides);
                b2CollidePolygons(&mani, &boxA, tranA, &polyB, tranB);
            }
            if (otroObj.getSides() == 5) {
                //  printf("RECTANGLE VS POLYGON 5 \n");
                int sides = otroObj.getSides();
                b2Vec2 points[sides];
                float scale = otroObj.getScale();
                float x, y;
                int k;
                b2PolygonShape polyB;
                float side = ((2 * scale) * sin(M_PI / sides));
                for (k = 0; k < sides; k++) {
                    x = side * cos(2 * M_PI * k / sides);
                    y = side * sin(2 * M_PI * k / sides);
                    points[k].Set(x, y);
                }
                polyB.Set(points, sides);
                b2CollidePolygons(&mani, &boxA, tranA, &polyB, tranB);
            }
            if (otroObj.getSides() == 6) {
                //   printf("RECTANGLE VS POLYGON 6 \n");
                int sides = otroObj.getSides();
                b2Vec2 points[sides];
                float scale = otroObj.getScale();
                float x, y;
                int k;
                b2PolygonShape polyB;
                float side = ((2 * scale) * sin(M_PI / sides));
                for (k = 0; k < sides; k++) {
                    x = side * cos(2 * M_PI * k / sides);
                    y = side * sin(2 * M_PI * k / sides);
                    points[k].Set(x, y);
                }
                polyB.Set(points, sides);
                b2CollidePolygons(&mani, &boxA, tranA, &polyB, tranB);
            }

        }//end polygon 

        if ((strcmp(otroObj.getType().c_str(), "PARALLELLOGRAM") == 0)) {

            b2PolygonShape polyB;
            float alphaB = otroObj.getAngle1();
            float sizeYB = otroObj.getHighParall() / 2;
            float sizeXB = otroObj.getBase() / 2;
            float sideB = (sizeYB) / sin(alphaB) * 2;
            float adyB = cos(alphaB) * sideB;
            b2Vec2 pointsB[4]; // paralelogramo = 4 lados
            pointsB[0].Set(adyB - (sizeXB), (-1)*(sizeYB));
            pointsB[1].Set(adyB + (sizeXB), (-1)*(sizeYB));
            pointsB[2].Set((sizeXB), (sizeYB));
            pointsB[3].Set((-1)*(sizeXB), (sizeYB));
            polyB.Set(pointsB, 4);
            b2CollidePolygons(&mani, &boxA, tranA, &polyB, tranB);
        }
        if ((strcmp(otroObj.getType().c_str(), "TRAPEZIUM") == 0)) {
            b2PolygonShape polyB;
            float sizeYB = otroObj.getHeight() / 2;
            float sizeXB = otroObj.getBase() / 2;
            float alphaB = otroObj.getAngle1();
            float betaB = otroObj.getAngle2();
            float adyAlphaB = sizeYB * cos(alphaB) / sin(alphaB) * 2;
            float adyBetaB = sizeYB * cos(betaB) / sin(betaB) * 2;
            b2Vec2 pointsB[4];
            pointsB[0].Set((-1) * sizeXB, sizeYB);
            pointsB[1].Set(sizeXB, sizeYB);
            pointsB[2].Set(sizeXB - adyBetaB, (-1) * sizeYB);
            pointsB[3].Set(adyAlphaB - sizeXB, (-1) * sizeYB);
            polyB.Set(pointsB, 4);
            b2CollidePolygons(&mani, &boxA, tranA, &polyB, tranB);
        }
    }

    //COMPARO CIRCLE CONTRA TODOS.
    if (strcmp(unObj.getType().c_str(), "CIRCLE") == 0) {
        b2CircleShape circle;
        circle.m_radius = borde + unObj.getScale();
        if (strcmp(otroObj.getType().c_str(), "CIRCLE") == 0) {
            // printf("CIRCLE VS CIRCLE \n");
            b2CircleShape circleB;
            circleB.m_radius = borde + otroObj.getScale();
            b2CollideCircles(&mani, &circle, tranA, &circleB, tranB);
        }
        if (strcmp(otroObj.getType().c_str(), "RECTANGLE") == 0) {
            //  printf("CIRCLE VS RECTANGLE \n");
            b2PolygonShape box;
            box.SetAsBox(borde + otroObj.getWidth() / 2, borde + otroObj.getHeight() / 2);
            b2CollidePolygonAndCircle(&mani, &box, tranB, &circle, tranA);
        }
        if (strcmp(otroObj.getType().c_str(), "POLYGON") == 0) {
            if (otroObj.getSides() == 3) {
                int sides = otroObj.getSides();
                b2Vec2 points[sides];
                float scale = otroObj.getScale();
                float x, y;
                int k;
                b2PolygonShape poly;
                float side = ((2 * scale) * sin(M_PI / sides));
                for (k = 0; k < sides; k++) {
                    x = side * cos(2 * M_PI * k / sides);
                    y = side * sin(2 * M_PI * k / sides);
                    points[k].Set(x, y);
                }
                poly.Set(points, sides);
                b2CollidePolygonAndCircle(&mani, &poly, tranB, &circle, tranA);
            }
            if (otroObj.getSides() == 5) {
                //  printf("CIRCLE VS POLYGON 5 \n");
                int sides = otroObj.getSides();
                b2Vec2 points[sides];
                float scale = otroObj.getScale();
                float x, y;
                int k;
                b2PolygonShape poly;
                float side = ((2 * scale) * sin(M_PI / sides));
                for (k = 0; k < sides; k++) {
                    x = side * cos(2 * M_PI * k / sides);
                    y = side * sin(2 * M_PI * k / sides);
                    points[k].Set(x, y);
                }
                poly.Set(points, sides);
                b2CollidePolygonAndCircle(&mani, &poly, tranB, &circle, tranA);
            }
            if (otroObj.getSides() == 6) {
                //  printf("CIRCLE VS POLYGON 5 \n");
                int sides = otroObj.getSides();
                b2Vec2 points[sides];
                float scale = otroObj.getScale();
                float x, y;
                int k;
                b2PolygonShape poly;
                float side = ((2 * scale) * sin(M_PI / sides));
                for (k = 0; k < sides; k++) {
                    x = side * cos(2 * M_PI * k / sides);
                    y = side * sin(2 * M_PI * k / sides);
                    points[k].Set(x, y);
                }
                poly.Set(points, sides);
                b2CollidePolygonAndCircle(&mani, &poly, tranB, &circle, tranA);
            }
        }
        if ((strcmp(otroObj.getType().c_str(), "PARALLELLOGRAM") == 0)) {

            b2PolygonShape polyB;
            float alphaB = otroObj.getAngle1();
            float sizeYB = otroObj.getHighParall() / 2;
            float sizeXB = otroObj.getBase() / 2;
            float sideB = (sizeYB) / sin(alphaB) * 2;
            float adyB = cos(alphaB) * sideB;
            b2Vec2 pointsB[4]; // paralelogramo = 4 lados
            pointsB[0].Set(adyB - (sizeXB), (-1)*(sizeYB));
            pointsB[1].Set(adyB + (sizeXB), (-1)*(sizeYB));
            pointsB[2].Set((sizeXB), (sizeYB));
            pointsB[3].Set((-1)*(sizeXB), (sizeYB));
            polyB.Set(pointsB, 4);

            b2CollidePolygonAndCircle(&mani, &polyB, tranB, &circle, tranA);
        }
        if ((strcmp(otroObj.getType().c_str(), "TRAPEZIUM") == 0)) {
            b2PolygonShape polyB;
            float sizeYB = otroObj.getHeight() / 2;
            float sizeXB = otroObj.getBase() / 2;
            float alphaB = otroObj.getAngle1();
            float betaB = otroObj.getAngle2();
            float adyAlphaB = sizeYB * cos(alphaB) / sin(alphaB) * 2;
            float adyBetaB = sizeYB * cos(betaB) / sin(betaB) * 2;
            b2Vec2 pointsB[4];
            pointsB[0].Set((-1) * sizeXB, sizeYB);
            pointsB[1].Set(sizeXB, sizeYB);
            pointsB[2].Set(sizeXB - adyBetaB, (-1) * sizeYB);
            pointsB[3].Set(adyAlphaB - sizeXB, (-1) * sizeYB);
            polyB.Set(pointsB, 4);
            b2CollidePolygonAndCircle(&mani, &polyB, tranB, &circle, tranA);
        }
    }//end Circle
    //INICIO POLIGONO CONTRA TODOS
    if ((strcmp(unObj.getType().c_str(), "POLYGON") == 0)) {
        //es un triangulo y comparo con todos.
        if (unObj.getSides() == 3) {
            //inicio POLYGON.
            int sides = unObj.getSides();
            b2Vec2 points[sides];
            float x, y;
            int k;
            //dif
            float scaleA = unObj.getScale();
            b2PolygonShape polyA;
            float sideA = ((2 * scaleA) * sin(M_PI / sides));
            for (k = 0; k < sides; k++) {
                x = sideA * cos(2 * M_PI * k / sides);
                y = sideA * sin(2 * M_PI * k / sides);
                points[k].Set(x, y);
            }
            polyA.Set(points, sides);
            if ((strcmp(otroObj.getType().c_str(), "POLYGON") == 0)) {
                if (otroObj.getSides() == 3) {
                    //                    printf("TRIANGULO VS TRIANGULO \n");
                    float scaleB = otroObj.getScale();
                    b2PolygonShape polyB;
                    float sideB = ((2 * scaleB) * sin(M_PI / otroObj.getSides()));
                    for (k = 0; k < otroObj.getSides(); k++) {
                        x = sideB * cos(2 * M_PI * k / otroObj.getSides());
                        y = sideB * sin(2 * M_PI * k / otroObj.getSides());
                        points[k].Set(x, y);
                    }
                    polyB.Set(points, sides);
                    b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
                }
                if (otroObj.getSides() == 5) {
                    //   printf("POLYGON 5 VS POLYGON 5 \n");
                    float scaleB = otroObj.getScale();
                    b2PolygonShape polyB;
                    float sideB = ((2 * scaleB) * sin(M_PI / otroObj.getSides()));
                    for (k = 0; k < otroObj.getSides(); k++) {
                        x = sideB * cos(2 * M_PI * k / otroObj.getSides());
                        y = sideB * sin(2 * M_PI * k / otroObj.getSides());
                        points[k].Set(x, y);
                    }
                    polyB.Set(points, sides);
                    b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
                }
                if (otroObj.getSides() == 6) {
                    //    printf("POLYGON 5 VS POLYGON 6 \n");
                    float scaleB = otroObj.getScale();
                    b2PolygonShape polyB;
                    float sideB = ((2 * scaleB) * sin(M_PI / otroObj.getSides()));
                    for (k = 0; k < otroObj.getSides(); k++) {
                        x = sideB * cos(2 * M_PI * k / otroObj.getSides());
                        y = sideB * sin(2 * M_PI * k / otroObj.getSides());
                        points[k].Set(x, y);
                    }
                    polyB.Set(points, otroObj.getSides());
                    b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
                }

            }//end Polygon
            if ((strcmp(otroObj.getType().c_str(), "RECTANGLE") == 0)) {
                //  printf("POLYGON 5 VS RECTANGLE \n");
                //inicio rectangle
                b2PolygonShape box;
                box.SetAsBox(borde + otroObj.getWidth() / 2, borde + otroObj.getHeight() / 2);
                b2CollidePolygons(&mani, &polyA, tranA, &box, tranB);
            }
            if ((strcmp(otroObj.getType().c_str(), "CIRCLE") == 0)) {
                //  printf("POLYGON 5 VS CIRCLE \n");
                b2CircleShape circle;
                circle.m_radius = borde + otroObj.getScale();
                b2CollidePolygonAndCircle(&mani, &polyA, tranA, &circle, tranB);
            }
            if ((strcmp(otroObj.getType().c_str(), "PARALLELLOGRAM") == 0)) {

                b2PolygonShape polyB;
                float alphaB = otroObj.getAngle1();
                float sizeYB = otroObj.getHighParall() / 2;
                float sizeXB = otroObj.getBase() / 2;
                float sideB = (sizeYB) / sin(alphaB) * 2;
                float adyB = cos(alphaB) * sideB;
                b2Vec2 pointsB[4]; // paralelogramo = 4 lados
                pointsB[0].Set(adyB - (sizeXB), (-1)*(sizeYB));
                pointsB[1].Set(adyB + (sizeXB), (-1)*(sizeYB));
                pointsB[2].Set((sizeXB), (sizeYB));
                pointsB[3].Set((-1)*(sizeXB), (sizeYB));
                polyB.Set(pointsB, 4);

                b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
            }
            if ((strcmp(otroObj.getType().c_str(), "TRAPEZIUM") == 0)) {
                b2PolygonShape polyB;
                float sizeYB = otroObj.getHeight() / 2;
                float sizeXB = otroObj.getBase() / 2;
                float alphaB = otroObj.getAngle1();
                float betaB = otroObj.getAngle2();
                float adyAlphaB = sizeYB * cos(alphaB) / sin(alphaB) * 2;
                float adyBetaB = sizeYB * cos(betaB) / sin(betaB) * 2;
                b2Vec2 pointsB[4];
                pointsB[0].Set((-1) * sizeXB, sizeYB);
                pointsB[1].Set(sizeXB, sizeYB);
                pointsB[2].Set(sizeXB - adyBetaB, (-1) * sizeYB);
                pointsB[3].Set(adyAlphaB - sizeXB, (-1) * sizeYB);
                polyB.Set(pointsB, 4);
                b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
            }

        }//end Triángulo
        //es un polygono de 5 lados y comparo con todos.
        if (unObj.getSides() == 5) {
            //inicio POLYGON.
            int sides = unObj.getSides();
            b2Vec2 points[sides];
            float x, y;
            int k;
            //dif
            float scaleA = unObj.getScale();
            b2PolygonShape polyA;
            float sideA = ((2 * scaleA) * sin(M_PI / sides));
            for (k = 0; k < sides; k++) {
                x = sideA * cos(2 * M_PI * k / sides);
                y = sideA * sin(2 * M_PI * k / sides);
                points[k].Set(x, y);
            }
            polyA.Set(points, sides);
            //comparo contra otro poligono.
            if ((strcmp(otroObj.getType().c_str(), "POLYGON") == 0)) {
                if (otroObj.getSides() == 3) {
                    float scaleB = otroObj.getScale();
                    b2PolygonShape polyB;
                    float sideB = ((2 * scaleB) * sin(M_PI / otroObj.getSides()));
                    for (k = 0; k < otroObj.getSides(); k++) {
                        x = sideB * cos(2 * M_PI * k / otroObj.getSides());
                        y = sideB * sin(2 * M_PI * k / otroObj.getSides());
                        points[k].Set(x, y);
                    }
                    polyB.Set(points, sides);
                    b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
                }
                if (otroObj.getSides() == 5) {
                    //   printf("POLYGON 5 VS POLYGON 5 \n");
                    float scaleB = otroObj.getScale();
                    b2PolygonShape polyB;
                    float sideB = ((2 * scaleB) * sin(M_PI / otroObj.getSides()));
                    for (k = 0; k < otroObj.getSides(); k++) {
                        x = sideB * cos(2 * M_PI * k / otroObj.getSides());
                        y = sideB * sin(2 * M_PI * k / otroObj.getSides());
                        points[k].Set(x, y);
                    }
                    polyB.Set(points, sides);
                    b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
                }
                if (otroObj.getSides() == 6) {
                    //    printf("POLYGON 5 VS POLYGON 6 \n");
                    float scaleB = otroObj.getScale();
                    b2PolygonShape polyB;
                    float sideB = ((2 * scaleB) * sin(M_PI / otroObj.getSides()));
                    for (k = 0; k < otroObj.getSides(); k++) {
                        x = sideB * cos(2 * M_PI * k / otroObj.getSides());
                        y = sideB * sin(2 * M_PI * k / otroObj.getSides());
                        points[k].Set(x, y);
                    }
                    polyB.Set(points, otroObj.getSides());
                    b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
                }

            }
            //comparo conta un rectangulo.
            if ((strcmp(otroObj.getType().c_str(), "RECTANGLE") == 0)) {
                //  printf("POLYGON 5 VS RECTANGLE \n");
                //inicio rectangle
                b2PolygonShape box;
                box.SetAsBox(borde + otroObj.getWidth() / 2, borde + otroObj.getHeight() / 2);
                b2CollidePolygons(&mani, &polyA, tranA, &box, tranB);
            }
            if ((strcmp(otroObj.getType().c_str(), "CIRCLE") == 0)) {
                //  printf("POLYGON 5 VS CIRCLE \n");
                b2CircleShape circle;
                circle.m_radius = borde + otroObj.getScale();
                b2CollidePolygonAndCircle(&mani, &polyA, tranA, &circle, tranB);
            }
            if ((strcmp(otroObj.getType().c_str(), "PARALLELLOGRAM") == 0)) {

                b2PolygonShape polyB;
                float alphaB = otroObj.getAngle1();
                float sizeYB = otroObj.getHighParall() / 2;
                float sizeXB = otroObj.getBase() / 2;
                float sideB = (sizeYB) / sin(alphaB) * 2;
                float adyB = cos(alphaB) * sideB;
                b2Vec2 pointsB[4]; // paralelogramo = 4 lados
                pointsB[0].Set(adyB - (sizeXB), (-1)*(sizeYB));
                pointsB[1].Set(adyB + (sizeXB), (-1)*(sizeYB));
                pointsB[2].Set((sizeXB), (sizeYB));
                pointsB[3].Set((-1)*(sizeXB), (sizeYB));
                polyB.Set(pointsB, 4);
                b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
            }
            if ((strcmp(otroObj.getType().c_str(), "TRAPEZIUM") == 0)) {
                b2PolygonShape polyB;
                float sizeYB = otroObj.getHeight() / 2;
                float sizeXB = otroObj.getBase() / 2;
                float alphaB = otroObj.getAngle1();
                float betaB = otroObj.getAngle2();
                float adyAlphaB = sizeYB * cos(alphaB) / sin(alphaB) * 2;
                float adyBetaB = sizeYB * cos(betaB) / sin(betaB) * 2;
                b2Vec2 pointsB[4];
                pointsB[0].Set((-1) * sizeXB, sizeYB);
                pointsB[1].Set(sizeXB, sizeYB);
                pointsB[2].Set(sizeXB - adyBetaB, (-1) * sizeYB);
                pointsB[3].Set(adyAlphaB - sizeXB, (-1) * sizeYB);
                polyB.Set(pointsB, 4);
                b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
            }

        }//polygon 5
        if (unObj.getSides() == 6) {
            //inicio POLYGON.
            int sides = unObj.getSides();
            b2Vec2 points[sides];
            float x, y;
            int k;
            //dif
            float scaleA = unObj.getScale();
            b2PolygonShape polyA;
            float sideA = ((2 * scaleA) * sin(M_PI / sides));
            for (k = 0; k < sides; k++) {
                x = sideA * cos(2 * M_PI * k / sides);
                y = sideA * sin(2 * M_PI * k / sides);
                points[k].Set(x, y);
            }
            polyA.Set(points, sides);
            //comparo contra poligonos.
            if ((strcmp(otroObj.getType().c_str(), "POLYGON") == 0)) {
                if (otroObj.getSides() == 3) {
                    //                    printf("TRIANGULO VS TRIANGULO \n");
                    float scaleB = otroObj.getScale();
                    b2PolygonShape polyB;
                    float sideB = ((2 * scaleB) * sin(M_PI / otroObj.getSides()));
                    for (k = 0; k < otroObj.getSides(); k++) {
                        x = sideB * cos(2 * M_PI * k / otroObj.getSides());
                        y = sideB * sin(2 * M_PI * k / otroObj.getSides());
                        points[k].Set(x, y);
                    }
                    polyB.Set(points, sides);
                    b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
                }
                if (otroObj.getSides() == 5) {
                    //   printf("POLYGON 6 VS POLYGON 5 \n");
                    float scaleB = otroObj.getScale();
                    b2PolygonShape polyB;
                    float sideB = ((2 * scaleB) * sin(M_PI / otroObj.getSides()));
                    for (k = 0; k < sides; k++) {
                        x = sideB * cos(2 * M_PI * k / otroObj.getSides());
                        y = sideB * sin(2 * M_PI * k / otroObj.getSides());
                        points[k].Set(x, y);
                    }
                    polyB.Set(points, otroObj.getSides());
                    b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
                }
                if (otroObj.getSides() == 6) {
                    //    printf("POLYGON 6 VS POLYGON 6 \n");
                    float scaleB = borde + otroObj.getScale();
                    b2PolygonShape polyB;
                    float sideB = ((2 * scaleB) * sin(M_PI / otroObj.getSides()));
                    for (k = 0; k < otroObj.getSides(); k++) {
                        x = sideB * cos(2 * M_PI * k / otroObj.getSides());
                        y = sideB * sin(2 * M_PI * k / otroObj.getSides());
                        points[k].Set(x, y);
                    }
                    polyB.Set(points, otroObj.getSides());
                    b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
                }
            }

            if ((strcmp(otroObj.getType().c_str(), "RECTANGLE") == 0)) {
                // printf("POLYGON 6 VS RECTANGLE \n");
                b2PolygonShape box;
                box.SetAsBox(borde + otroObj.getWidth() / 2, borde + otroObj.getHeight() / 2);
                b2CollidePolygons(&mani, &polyA, tranA, &box, tranB);
            }
            if ((strcmp(otroObj.getType().c_str(), "CIRCLE") == 0)) {
                // printf("POLYGON 6 VS CIRCLE \n");
                b2CircleShape circle;
                circle.m_radius = borde + otroObj.getScale();
                b2CollidePolygonAndCircle(&mani, &polyA, tranA, &circle, tranB);
            }
            if ((strcmp(otroObj.getType().c_str(), "PARALLELLOGRAM") == 0)) {

                b2PolygonShape polyB;
                float alphaB = otroObj.getAngle1();
                float sizeYB = otroObj.getHighParall() / 2;
                float sizeXB = otroObj.getBase() / 2;
                float sideB = (sizeYB) / sin(alphaB) * 2;
                float adyB = cos(alphaB) * sideB;
                b2Vec2 pointsB[4]; // paralelogramo = 4 lados
                pointsB[0].Set(adyB - (sizeXB), (-1)*(sizeYB));
                pointsB[1].Set(adyB + (sizeXB), (-1)*(sizeYB));
                pointsB[2].Set((sizeXB), (sizeYB));
                pointsB[3].Set((-1)*(sizeXB), (sizeYB));
                polyB.Set(pointsB, 4);
                b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
            }
            if ((strcmp(otroObj.getType().c_str(), "TRAPEZIUM") == 0)) {
                b2PolygonShape polyB;
                float sizeYB = otroObj.getHeight() / 2;
                float sizeXB = otroObj.getBase() / 2;
                float alphaB = otroObj.getAngle1();
                float betaB = otroObj.getAngle2();
                float adyAlphaB = sizeYB * cos(alphaB) / sin(alphaB) * 2;
                float adyBetaB = sizeYB * cos(betaB) / sin(betaB) * 2;
                b2Vec2 pointsB[4];
                pointsB[0].Set((-1) * sizeXB, sizeYB);
                pointsB[1].Set(sizeXB, sizeYB);
                pointsB[2].Set(sizeXB - adyBetaB, (-1) * sizeYB);
                pointsB[3].Set(adyAlphaB - sizeXB, (-1) * sizeYB);
                polyB.Set(pointsB, 4);
                b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
            }
        }//polygon 6
    }//END polygon

    //INICIO PARALLELLOGRAM CONTRA TODOS
    if ((strcmp(unObj.getType().c_str(), "PARALLELLOGRAM") == 0)) {

        b2PolygonShape polyA;
        float alpha = unObj.getAngle1();
        float sizeY = unObj.getHighParall() / 2;
        float sizeX = unObj.getBase() / 2;
        //        printf("UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUN alphaB: %4.3f sizeYB:%4.3f  sizeXB:%4.3f \n", alpha, sizeY, sizeX);
        float side = (sizeY) / sin(alpha) * 2;
        float ady = cos(alpha) * side;
        b2Vec2 points[4]; // paralelogramo = 4 lados
        points[0].Set(ady - (sizeX), (-1)*(sizeY));
        points[1].Set(ady + (sizeX), (-1)*(sizeY));
        points[2].Set((sizeX), (sizeY));
        points[3].Set((-1)*(sizeX), (sizeY));
        //        printf("UNNNNNNNNNNNNNNNNNN  POOOOOOOOOOOOOOOOOOOOOOINTS\n");
        //        printf("points[0] x: %4.3f y: %4.3f\n", points[0].x, points[0].y);
        //        printf("points[1] x: %4.3f y: %4.3f\n", points[1].x, points[1].y);
        //        printf("points[2] x: %4.3f y: %4.3f\n", points[2].x, points[2].y);
        //        printf("points[3] x: %4.3f y: %4.3f\n", points[3].x, points[3].y);

        polyA.Set(points, 4);
        if ((strcmp(otroObj.getType().c_str(), "PARALLELLOGRAM") == 0)) {

            b2PolygonShape polyB;
            float alphaB = otroObj.getAngle1();
            float sizeYB = otroObj.getHighParall() / 2;
            float sizeXB = otroObj.getBase() / 2;
            //            printf(" OTROOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO alphaB: %4.3f sizeYB:%4.3f  sizeXB:%4.3f \n", alphaB, sizeYB, sizeXB);
            float sideB = (sizeYB) / sin(alphaB) * 2;
            float adyB = cos(alphaB) * sideB;
            b2Vec2 pointsB[4]; // paralelogramo = 4 lados
            pointsB[0].Set(adyB - (sizeXB), (-1)*(sizeYB));
            pointsB[1].Set(adyB + (sizeXB), (-1)*(sizeYB));
            pointsB[2].Set((sizeXB), (sizeYB));
            pointsB[3].Set((-1)*(sizeXB), (sizeYB));
            //            printf("OTROOOOOOOOOOOOO  POOOOOOOOOOOOOOOOOOOOOOINTS\n");
            //            printf("points[0] x: %4.3f y: %4.3f\n", pointsB[0].x, pointsB[0].y);
            //            printf("points[1] x: %4.3f y: %4.3f\n", pointsB[1].x, pointsB[1].y);
            //            printf("points[2] x: %4.3f y: %4.3f\n", pointsB[2].x, pointsB[2].y);
            //            printf("points[3] x: %4.3f y: %4.3f\n", pointsB[3].x, pointsB[3].y);

            polyB.Set(pointsB, 4);
            b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
        }

        if ((strcmp(otroObj.getType().c_str(), "POLYGON") == 0)) {
            if (otroObj.getSides() == 3) {
                int sides = otroObj.getSides();
                b2Vec2 points[sides];
                float scale = otroObj.getScale();
                float x, y;
                int k;
                b2PolygonShape polyB;
                float side = ((2 * scale) * sin(M_PI / sides));
                for (k = 0; k < sides; k++) {
                    x = side * cos(2 * M_PI * k / sides);
                    y = side * sin(2 * M_PI * k / sides);
                    points[k].Set(x, y);
                }
                polyB.Set(points, sides);
                b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
            }
            if (otroObj.getSides() == 5) {

                float x, y;
                float scaleB = otroObj.getScale();
                b2PolygonShape polyB;
                float sideB = ((2 * scaleB) * sin(M_PI / otroObj.getSides()));
                for (int k = 0; k < otroObj.getSides(); k++) {
                    x = sideB * cos(2 * M_PI * k / otroObj.getSides());
                    y = sideB * sin(2 * M_PI * k / otroObj.getSides());
                    points[k].Set(x, y);
                }
                polyB.Set(points, otroObj.getSides());
                b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
            }
            if (otroObj.getSides() == 6) {

                float x, y;
                float scaleB = borde + otroObj.getScale();
                b2PolygonShape polyB;
                float sideB = ((2 * scaleB) * sin(M_PI / otroObj.getSides()));
                for (int k = 0; k < otroObj.getSides(); k++) {
                    x = sideB * cos(2 * M_PI * k / otroObj.getSides());
                    y = sideB * sin(2 * M_PI * k / otroObj.getSides());
                    points[k].Set(x, y);
                }
                polyB.Set(points, otroObj.getSides());
                b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
            }

        }
        if ((strcmp(otroObj.getType().c_str(), "RECTANGLE") == 0)) {

            b2PolygonShape box;
            box.SetAsBox(borde + otroObj.getWidth() / 2, borde + otroObj.getHeight() / 2);
            b2CollidePolygons(&mani, &polyA, tranA, &box, tranB);
        }
        if ((strcmp(otroObj.getType().c_str(), "CIRCLE") == 0)) {

            b2CircleShape circle;
            circle.m_radius = borde + otroObj.getScale();
            b2CollidePolygonAndCircle(&mani, &polyA, tranA, &circle, tranB);
        }
        if ((strcmp(otroObj.getType().c_str(), "TRAPEZIUM") == 0)) {
            b2PolygonShape polyB;
            float sizeYB = otroObj.getHeight() / 2;
            float sizeXB = otroObj.getBase() / 2;
            float alphaB = otroObj.getAngle1();
            float betaB = otroObj.getAngle2();
            float adyAlphaB = sizeYB * cos(alphaB) / sin(alphaB) * 2;
            float adyBetaB = sizeYB * cos(betaB) / sin(betaB) * 2;
            b2Vec2 pointsB[4];
            pointsB[0].Set((-1) * sizeXB, sizeYB);
            pointsB[1].Set(sizeXB, sizeYB);
            pointsB[2].Set(sizeXB - adyBetaB, (-1) * sizeYB);
            pointsB[3].Set(adyAlphaB - sizeXB, (-1) * sizeYB);
            polyB.Set(pointsB, 4);
            b2CollidePolygons(&mani, &polyA, tranA, &polyB, tranB);
        }

    }
    if (mani.pointCount > 0) {
        //        printf("PUNTOS FIN CONTACTO: %d \n", mani.pointCount);
        //agregar error log.
        return true;
    }
    return false;
}

void FileWindow::filterOverlap() {
    vector<FileObjects> objetosDeEntrada = this->getObjects();
    vector<FileObjects> *vecResult = new vector<FileObjects>();
    //contenedores
    vector<FileObjects> *rectangle = new vector<FileObjects>();
    vector<FileObjects> *circle = new vector<FileObjects>();
    vector<FileObjects> *polygonThree = new vector<FileObjects>();
    vector<FileObjects> *polygonFive = new vector<FileObjects>();
    vector<FileObjects> *polygonSix = new vector<FileObjects>();
    vector<FileObjects> *parallellogram = new vector<FileObjects>();
    vector<FileObjects> *trapezium = new vector<FileObjects>();

    //guardo el primer elemento. El primer elemento es el piso.
    vecResult->push_back(objetosDeEntrada.at(0));
    if (strcmp(objetosDeEntrada.at(0).getType().c_str(), "RECTANGLE") == 0) {
        rectangle->push_back(objetosDeEntrada.at(0));
    }
    if (strcmp(objetosDeEntrada.at(0).getType().c_str(), "TRAPEZIUM") == 0) {
        trapezium->push_back(objetosDeEntrada.at(0));
    }
    if (strcmp(objetosDeEntrada.at(0).getType().c_str(), "CIRCLE") == 0) {
        circle->push_back(objetosDeEntrada.at(0));
    }
    if (strcmp(objetosDeEntrada.at(0).getType().c_str(), "POLYGON") == 0) {
        if (objetosDeEntrada.at(0).getSides() == 3) {
            polygonThree->push_back(objetosDeEntrada.at(0));
        }
        if (objetosDeEntrada.at(0).getSides() == 5) {
            polygonFive->push_back(objetosDeEntrada.at(0));
        }
        if (objetosDeEntrada.at(0).getSides() == 6) {
            polygonSix->push_back(objetosDeEntrada.at(0));
        }
    }
    if (strcmp(objetosDeEntrada.at(0).getType().c_str(), "PARALLELLOGRAM") == 0) {
        parallellogram->push_back(objetosDeEntrada.at(0));
    }

    //Inicia en 1 , dado que el primer elemento que agrego al mundo es el piso.
    for (int i = 1; i < objetosDeEntrada.size(); i++) {
        int j = 0;
        int sizeResult = vecResult->size();
        bool ok = false;
        while (j < vecResult->size() && !ok) {
            if (overlap(objetosDeEntrada.at(i), vecResult->at(j))) {
                //no guardo el elemento y paso al siguiente de la lista.
                ok = true;
            }
            j++;
        }
        if (!ok) {

            if (strcmp(objetosDeEntrada.at(i).getType().c_str(), "RECTANGLE") == 0) {
                //                printf ("RECTANGLEEEEEEE: %d \n",objetosDeEntrada.at(i).getXCoordinate());

                rectangle->push_back(objetosDeEntrada.at(i));
            }
            if (strcmp(objetosDeEntrada.at(i).getType().c_str(), "TRAPEZIUM") == 0) {
                //                printf ("TRAPEZIUMMMM: %d \n",objetosDeEntrada.at(i).getXCoordinate());
                trapezium->push_back(objetosDeEntrada.at(i));
            }

            if (strcmp(objetosDeEntrada.at(i).getType().c_str(), "CIRCLE") == 0) {
                //                printf ("CIRCLEEEEEE: %d \n",objetosDeEntrada.at(i).getXCoordinate());
                circle->push_back(objetosDeEntrada.at(i));
            }
            if (strcmp(objetosDeEntrada.at(i).getType().c_str(), "POLYGON") == 0) {
                if (objetosDeEntrada.at(i).getSides() == 3) {
                    //                    printf ("POLYGONNNNN3 : %d \n",objetosDeEntrada.at(i).getXCoordinate());
                    polygonThree->push_back(objetosDeEntrada.at(i));
                }
                if (objetosDeEntrada.at(i).getSides() == 5) {
                    //                printf (" POLYGONNNNN3 :%d \n",objetosDeEntrada.at(i).getXCoordinate());
                    polygonFive->push_back(objetosDeEntrada.at(i));
                }
                if (objetosDeEntrada.at(i).getSides() == 6) {
                    //                printf (" POLYGONNNNN3 :%d \n",objetosDeEntrada.at(i).getXCoordinate());
                    polygonSix->push_back(objetosDeEntrada.at(i));
                }
            }
            if (strcmp(objetosDeEntrada.at(i).getType().c_str(), "PARALLELLOGRAM") == 0) {
                //               printf (" POLYGONNNNN3 :%d \n",objetosDeEntrada.at(i).getXCoordinate());
                parallellogram->push_back(objetosDeEntrada.at(i));
            }
            vecResult->push_back(objetosDeEntrada.at(i));
        } else {
            SBSLog* myLogFile;
            
            myLogFile->writeInLog(1, "El objeto  ");
            myLogFile->writeInLog(1, objetosDeEntrada.at(i).getType().c_str());
            myLogFile->writeInLog(1, "  no se agrego al escenario (por superposicion)\n");
        }
    }
    this->endObject = vecResult;
    this->rectangle = rectangle;
    this->circle = circle;
    this->polygonFive = polygonFive;
    this->polygonSix = polygonSix;
    this->parrallellogram = parallellogram;
    this->polygonThree = polygonThree;
    this->trapezium = trapezium;
}

vector<FileObjects>* FileWindow::getEndObject() {
    //cambiar de lugar si o si.
    this->filterOverlap();
    return this->endObject;
}

vector<FileObjects>* FileWindow::getTrapezium() {
    return this->trapezium;
}

vector<FileObjects>* FileWindow::getRectangle() {
    return this->rectangle;
}

vector<FileObjects>* FileWindow::getCircle() {
    return this->circle;
}

vector<FileObjects>* FileWindow::getPolygon(int sides) {
    if (sides == 3) {
        return this->polygonThree;
    }
    if (sides == 5) {
        return this->polygonFive;
    }
    if (sides == 6) {
        return this->polygonSix;
    }
}

vector<FileObjects>* FileWindow::getParrallellogram() {
    return this->parrallellogram;
}

string FileWindow::getName() {
    return this -> name;
}

string FileWindow::getBackGround() {
    return this -> backGround;
}

float FileWindow::getGravity() {
    return this -> gravity;
}

int FileWindow::getPixelHeight() {
    return this -> pixelHeight;
}

int FileWindow::getPixelWidth() {
    return this -> pixelWidth;
}

int FileWindow::getLogicalUnitHeight() {
    return this -> logicalUnitH;
}

int FileWindow::getLogicalUnitWidth() {
    return this -> logicalUnitW;
}

int FileWindow::getObjectsNumber() {
    return this -> objectsNumber;
}


int FileWindow::getPlayerXLocation(int idPlayer) {
    return this -> players.at(idPlayer-1).getXCoordinate();
}

int FileWindow::getPlayerYLocation(int idPlayer) {
    return this -> players.at(idPlayer-1).getYCoordinate();
}

int FileWindow::getMaxPlayers (){
    return this->maxPlayers;
}

vector <FileObjects> FileWindow::getObjects() {
    return this -> objects;
}

vector <FileCharacter> FileWindow::getPlayers(){
    return this->players;
}


